#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
文本分词处理模块（改进版）
对URL和User-Agent字段进行分词处理，重点优化URL中的SQL注入、攻击特征提取
"""

import jieba
import re
import urllib.parse
from typing import List


def tokenize_url(url: str) -> list:
    """
    对 URL 进行定制化分词，规则如下：
    1. 只要出现两个及以上连续的字母（a-zA-Z），就认为是一个 token 的开始
    2. 后面可以跟任意数量的字母（a-zA-Z）或数字（0-9）
    3. 允许下划线 _ 连接字母/数字，如 abc_123, var_name, func_abc_99，视为一个整体 token
    4. 一旦遇到非字母、非数字、且非下划线（如 ? = & [ ] { } 空格 / . - 等），就终止当前 token
    5. 不再使用传统正则过滤，而是严格按上述规则动态识别 token

    Args:
        url (str): 输入的 URL 字符串，可能包含路径、参数、查询字符串等

    Returns:
        list: 分词后的 token 列表，如 ['index', 'php', 'vars', 'md5', 'hello', 'think']
    """
    # 先判读url中是否存在%
    times = 20
    while '%' in url and times > 0:
        url = urllib.parse.unquote(url)
        times -= 1
    tokens = []
    current_token = []
    in_token = False
    letter_count = 0  # 用于判断是否以两个字母开头

    for char in url:
        is_alpha = char.isalpha()
        is_digit = char.isdigit()
        is_underscore = char == '_'

        if is_alpha or is_digit or is_underscore:
            current_token.append(char)
            if is_alpha:
                letter_count += 1
            in_token = True
        else:
            if in_token and letter_count >= 2:
                tokens.append(''.join(current_token))
            current_token = []
            letter_count = 0
            in_token = False

    # 处理文本末尾可能还有一个 token
    if in_token and letter_count >= 2:
        tokens.append(''.join(current_token))

    return tokens


def tokenize_user_agent(user_agent):
    """
    对User-Agent进行分词处理（原逻辑保持不变，仅优化注释与健壮性）

    Args:
        user_agent (str): User-Agent字符串

    Returns:
        list: 分词结果列表
    """
    try:
        if not user_agent or user_agent.strip() == '':
            return ['EMPTY_UA']

        tokens = []

        lower_ua = user_agent.lower()

        # 浏览器识别
        if 'chrome' in lower_ua:
            tokens.append('CHROME_BROWSER')
        elif 'firefox' in lower_ua:
            tokens.append('FIREFOX_BROWSER')
        elif 'safari' in lower_ua:
            tokens.append('SAFARI_BROWSER')
        elif 'edge' in lower_ua:
            tokens.append('EDGE_BROWSER')
        elif 'opera' in lower_ua:
            tokens.append('OPERA_BROWSER')
        elif 'msie' in lower_ua or 'trident' in lower_ua:
            tokens.append('IE_BROWSER')

        # 操作系统
        if 'windows' in lower_ua:
            tokens.append('WINDOWS_OS')
        elif 'macintosh' in lower_ua or 'mac os' in lower_ua:
            tokens.append('MAC_OS')
        elif 'linux' in lower_ua:
            tokens.append('LINUX_OS')
        elif 'android' in lower_ua:
            tokens.append('ANDROID_OS')
        elif 'iphone' in lower_ua or 'ipad' in lower_ua:
            tokens.append('IOS_DEVICE')

        # 爬虫检测
        crawler_keywords = ['bot', 'spider', 'crawler', 'python', 'java', 'curl', 'wget', 'requests']
        if any(keyword.lower() in lower_ua for keyword in crawler_keywords):
            tokens.append('CRAWLER_AGENT')

        # 对UA进行基础分词
        ua_words = jieba.lcut(user_agent)
        filtered_ua_words = [word for word in ua_words if (len(word) > 1 or word.isdigit()) and word.strip()]
        tokens.extend(filtered_ua_words)

        # 保底逻辑
        if len(tokens) <= 1:
            keywords = re.findall(r'[a-zA-Z]+', user_agent)
            tokens.extend(keywords[:10])
        # 删除tokens中的所有数字和浮点数
        tokens = [token for token in tokens if not (token.isdigit() or token.replace('.', '', 1).isdigit())]

        # 输出分词结果
        #print(f"[tokenize_user_agent] 输入: {user_agent}, 输出: {tokens}")

        return tokens

    except Exception as e:
        print(f"[tokenize_user_agent] 错误: {e}")
        return ['UA_ERROR', user_agent[:20]]


def process_text_field(text, field_type='url'):
    if field_type == 'url':
        return tokenize_url(text)
    elif field_type == 'user_agent':
        return tokenize_user_agent(text)
    else:
        if text and text.strip():
            return jieba.lcut(str(text))
        else:
            return ['EMPTY_TEXT']